
﻿using Newtonsoft.Json.Linq;
using SKIT.FlurlHttpClient.Wechat.TenpayV3;
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Models;

﻿using drinking.Helpers;
using drinking.Models;

using System.Text;

namespace drinking.Managers
{
    public class WxManager
    {

        public static readonly string APPID = "wxa3163dda07feb8bb";
        private static readonly string APPSECRET = "22aeb5706ecbbae55289955068a7c7fd";

        private static Object o_lock = new Object();

        private static string access_token;
        public static string AccessToken
        {
            get
            {
                // 涉及到多个线程读和取值， 需要加锁
                lock (o_lock)
                {
                    if (access_token == null)
                    {
                        access_token = GetAccess_token();
                    }
                    return access_token;
                }

            }

            set
            {
                lock (o_lock)
                {
                    access_token = value;
                }

            }
        }

        /// <summary>
        /// 获取访问微信api的Access_token, 
        /// </summary>
        /// <returns></returns>
        public static string GetAccess_token()
        {
            HttpClient client = new HttpClient();
            client.Timeout = new TimeSpan(0, 0, 5);
            var httpmessage = client.GetAsync($"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={APPID}&secret={APPSECRET}").Result;
            httpmessage.EnsureSuccessStatusCode();

            var results = httpmessage.Content.ReadAsStringAsync().Result;

            if (results != null)
            {
                JObject data = JObject.Parse(results);
                var access_token = data["access_token"];
                return (string)access_token;
            }
            return null;
        }
        /// <summary>
        /// 调用微信api接口，用小程序穿过来的code，向微信服务器请求得到openid
        /// </summary>
        /// <param name="_code">小程序穿过来的code</param>
        /// <returns></returns>
        public static string GetUserOpenId(string js_code)
        {
            HttpClient client = new HttpClient();
            client.Timeout = new TimeSpan(0, 0, 5);
            var httpmessage = client.PostAsync($" https://api.weixin.qq.com/sns/jscode2session?appid={APPID}&secret={APPSECRET}&js_code={js_code}&grant_type=authorization_code"
                   , new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(new { code = js_code })
                   , Encoding.UTF8, "application/json")).Result;
            httpmessage.EnsureSuccessStatusCode();

            var results = httpmessage.Content.ReadAsStringAsync().Result;
            if (results != null)
            {
                JObject data = JObject.Parse(results);
                return (string)data["openid"];
            }
            return null;
        }

        /// <summary>
        /// 调用微信api接口，用小程序穿过来的code，向微信服务器请求得到手机号
        /// </summary>
        /// <param name="_code">小程序穿过来的code</param>
        /// <returns></returns>
        public static string GetUserPhoneNumber(string _code)
        {
            HttpClient client = new HttpClient();
            client.Timeout = new TimeSpan(0, 0, 5);
            var httpmessage = client.PostAsync($"https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token={AccessToken}"
                   , new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(new { code = _code })
                   , Encoding.UTF8, "application/json")).Result;
            httpmessage.EnsureSuccessStatusCode();

            var results = httpmessage.Content.ReadAsStringAsync().Result;
            if (results != null)
            {
                JObject data = JObject.Parse(results);
                var errcode = data["errcode"];
                if (((int)errcode) == 0)
                {
                    return (string)(data["phone_info"] as JObject)["purePhoneNumber"];
                }
            }
            return null;
        }

        /// <summary>
        /// access_token 每2个小时失效一次,因此需要定时任务来更新
        /// </summary>
        public static Timer AccessTokenRefreshTime {get; private set;} = new Timer((obj) =>
            {
                try
                {
                    string access_token = GetAccess_token();
                    if (!string.IsNullOrEmpty(access_token))
                    {
                        AccessToken = access_token;
                    }
                }
                catch { }
                
            });

    }
}
